/**************************************************************************** 
* 
* Copyright (c) 2023  C*Core -   All Rights Reserved  
* 
* THIS SOFTWARE IS DISTRIBUTED "AS IS," AND ALL WARRANTIES ARE DISCLAIMED, 
* INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* 
* PROJECT     : CCFC2011BC           
* DESCRIPTION : icu demo code 
* HISTORY     : Initial version.
* @file     iic_demo.c
* @version  1.1
* @date     2023 - 02 - 20
* @brief    Initial version.
*
*****************************************************************************/
#include "icu_demo.h"
#include "pwm_demo.h"
#include "led_hw.h"
#include "console.h"
#include "intc_lld.h"

/*******************************************************************************
 * @brief      icuedgecount1
 * @param[in]  const ICUDriver *icudriver
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void icuedgecount1(const ICUDriver *icudriver) /* PRQA S 3206 */
{
    icudriver = icudriver; /* PRQA S 1338, 2983 */
    LED_Set(LED1, 0);
}

/*******************************************************************************
 * @brief      icutimestamp1
 * @param[in]  const ICUDriver *icudriver
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void icutimestamp1(const ICUDriver *icudriver) /* PRQA S 3206 */
{
    icudriver = icudriver; /* PRQA S 1338, 2983 */
    LED_Set(LED1, 0);
}

/*******************************************************************************
 * @brief      icuwidthcb1
 * @param[in]  const ICUDriver *icudriver
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void icuwidthcb1(const ICUDriver *icudriver) /* PRQA S 3206 */
{
    icudriver = icudriver; /* PRQA S 1338, 2983 */
    LED_Set(LED1, 0);
}

/*******************************************************************************
 * @brief      icuperiodcb1
 * @param[in]  const ICUDriver *icudriver
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void icuperiodcb1(const ICUDriver *icudriver) /* PRQA S 3206 */
{
    icudriver = icudriver; /* PRQA S 1338, 2983 */
    LED_Set(LED1, 0);
}

/*******************************************************************************
 * @brief      icuipwmcb1
 * @param[in]  const ICUDriver *icudriver
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void icuipwmcb1(const ICUDriver *icudriver) /* PRQA S 3206 */
{
    icudriver = icudriver; /* PRQA S 1338, 2983 */
    LED_Set(LED1, 0);
}

/*******************************************************************************
 * @brief      icuipmcb1
 * @param[in]  const ICUDriver *icudriver
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void icuipmcb1(const ICUDriver *icudriver) /* PRQA S 3206 */
{
    icudriver = icudriver; /* PRQA S 1338, 2983 */
    LED_Set(LED1, 1);
}

/*******************************************************************************
 * @brief      ICU_Test_Case1
 *             Application entry point.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case1(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    uint8_t const ch_num[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 23, 24};
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_SINGLE_ACTION_MODE;
    config.config_saic.usermode = ICU_USER_MODE_EDGE_COUNTER;
    config.config_saic.clock_bus = ICU_INTERNAL_COUNTER;
    config.config_saic.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_saic.edge_polarity = RISING_EDGE;
    config.config_saic.edge_count_cb = icuedgecount1;
    ICU_LLD_Init(&ICUD_0, &EMIOS_0, 64);

    for (i = 0U; i < 12U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, ch_num[i], &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, ch_num[i]);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, ch_num[i]);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, ch_num[i]);
        PSPRINTF("\n chnnel_number = %d!\n", ch_num[i]);
        PSPRINTF("\n edge_numbers = %d!\n", ICUD_0.data.saic_data.edge_numbers[ch_num[i]]);
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case2
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case2(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    uint8_t const ch_num[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 23, 24};
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_SINGLE_ACTION_MODE;
    config.config_saic.usermode = ICU_USER_MODE_TIME_STAMP;
    config.config_saic.clock_bus = ICU_INTERNAL_COUNTER;
    config.config_saic.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_saic.edge_polarity = RISING_EDGE;
    config.config_saic.time_stamp_cb = icutimestamp1;

    ICU_LLD_Init(&ICUD_0, &EMIOS_0, 64);

    for (i = 0U; i < 12U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, ch_num[i], &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, ch_num[i]);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, ch_num[i]);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, ch_num[i]);
        PSPRINTF("\n chnnel_number = %d!\n", ch_num[i]);
        PSPRINTF("\n time_stamp = %d!\n", ICUD_0.data.saic_data.time_stamp[ch_num[i]]);
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case3
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case3(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    uint8_t const ch_num[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 23, 24};
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_SINGLE_ACTION_MODE;
    config.config_saic.usermode = ICU_USER_MODE_WIDTH_PERIOD_MEASUREMENT;
    config.config_saic.clock_bus = ICU_INTERNAL_COUNTER;
    config.config_saic.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_saic.edge_polarity = BOTH_EDGE;
    config.config_saic.width_cb = icuwidthcb1;
    config.config_saic.period_cb = icuperiodcb1;

    ICU_LLD_Init(&ICUD_0, &EMIOS_0, 64);

    for (i = 0U; i < 12U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, ch_num[i], &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, ch_num[i]);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, ch_num[i]);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, ch_num[i]);
        PSPRINTF("\n chnnel_number = %d!\n", ch_num[i]);
        PSPRINTF("\n with = %d!\n", ICUD_0.data.saic_data.width[ch_num[i]]);
        PSPRINTF("\n period = %d!\n", ICUD_0.data.saic_data.period[ch_num[i]]);
        if (ICUD_0.data.saic_data.period[ch_num[i]] != 0U)
        {
            PSPRINTF("\n wave frequency = %d Hz!\n", (ICU_LLD_GetFrequency(&ICUD_0, ch_num[i])));
            PSPRINTF("\n DutyCycle = %f %%!\n", (ICU_LLD_GetDutyCycle(&ICUD_0, ch_num[i])));
        }
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case4
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case4(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_PULSE_WIDTH_MEASUREMENT_MODE;
    config.config_ipwm.clock_bus = ICU_INTERNAL_COUNTER;
    config.config_ipwm.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_ipwm.edge_polarity = RISING_EDGE;
    config.config_ipwm.ipwm_cb = icuipwmcb1;

    ICU_LLD_Init(&ICUD_0, &EMIOS_0, 64);

    for (i = 1U; i < 8U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, i, &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, i);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, i);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, i);
        PSPRINTF("\n chnnel_number = %d!\n", i);
        PSPRINTF("\n width time = %d us!\n", ICU_LLD_GetTimeElapsed(&ICUD_0, i));
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case5
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case5(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_PERIOD_WIDTH_MEASUREMENT_MODE;
    config.config_ipm.clock_bus = ICU_INTERNAL_COUNTER;
    config.config_ipm.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_ipm.edge_polarity = RISING_EDGE;
    config.config_ipm.ipw_cb = icuipmcb1;

    ICU_LLD_Init(&ICUD_0, &EMIOS_0, 64);

    for (i = 1U; i < 8U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, i, &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, i);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, i);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, i);
        PSPRINTF("\n chnnel_number = %d!\n", i);
        PSPRINTF("\n preiod time = %d  us!\n", ICU_LLD_GetPeriodTime(&ICUD_0, i));
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case6
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case6(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_SINGLE_ACTION_MODE;
    config.config_saic.usermode = ICU_USER_MODE_EDGE_COUNTER;
    config.config_saic.clock_bus = ICU_COUNTER_BUS_A;
    config.config_saic.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_saic.edge_polarity = RISING_EDGE;
    config.config_saic.edge_count_cb = icuedgecount1;

    PWM_MCB_ICU_USE();

    /* icudriver Init*/
    ICUD_0.emiosp = &EMIOS_0;
    ICUD_0.ch_num.R = 0;
    ICUD_0.sys_clock = 64000000;
    ICUD_0.emios_prescale = 64;

    for (i = 0U; i < 32U; i++)
    {
        ICUD_0.data.saic_data.edge_numbers[i] = 0;
        ICUD_0.data.saic_data.time_stamp[i] = 0;
        ICUD_0.data.saic_data.width[i] = 0;
        ICUD_0.data.saic_data.pe.a2_1 = 0;
        ICUD_0.data.saic_data.pe.a2_2 = 0;
        ICUD_0.data.saic_data.pe.a2_3 = 0;
        ICUD_0.data.saic_data.period[i] = 0;
        ICUD_0.data.ipwm_data.time_stamp1[i] = 0;
        ICUD_0.data.ipwm_data.time_stamp2[i] = 0;
        ICUD_0.data.ipwm_data.pulse_width_numbers[i] = 0;
        ICUD_0.data.ipm_data.time_stamp1[i] = 0;
        ICUD_0.data.ipm_data.time_stamp2[i] = 0;
        ICUD_0.data.ipm_data.period_numbers[i] = 0;
    }

    for (i = 0U; i < 23U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, i, &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, i);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, i);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, i);
        PSPRINTF("\n chnnel_number = %d!\n", i);
        PSPRINTF("\n edge_numbers = %d!\n", ICUD_0.data.saic_data.edge_numbers[i]);
    }

    for (i = 24U; i < 32U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, i, &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, i);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, i);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, i);
        PSPRINTF("\n chnnel_number = %d!\n", i);
        PSPRINTF("\n edge_numbers = %d!\n", ICUD_0.data.saic_data.edge_numbers[i]);
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case7
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case7(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    uint8_t const ch_num[14] = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15};
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_PULSE_WIDTH_MEASUREMENT_MODE;
    config.config_ipwm.clock_bus = ICU_COUNTER_BUS_A;
    config.config_ipwm.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_ipwm.edge_polarity = RISING_EDGE;
    config.config_ipwm.ipwm_cb = icuipwmcb1;

    PWM_MCB_ICU_USE();

    /* icudriver Init*/
    ICUD_0.emiosp = &EMIOS_0;
    ICUD_0.ch_num.R = 0;
    ICUD_0.sys_clock = 64000000;
    ICUD_0.emios_prescale = 64;

    for (i = 0U; i < 32U; i++)
    {
        ICUD_0.data.saic_data.edge_numbers[i] = 0;
        ICUD_0.data.saic_data.time_stamp[i] = 0;
        ICUD_0.data.saic_data.width[i] = 0;
        ICUD_0.data.saic_data.pe.a2_1 = 0;
        ICUD_0.data.saic_data.pe.a2_2 = 0;
        ICUD_0.data.saic_data.pe.a2_3 = 0;
        ICUD_0.data.saic_data.period[i] = 0;
        ICUD_0.data.ipwm_data.time_stamp1[i] = 0;
        ICUD_0.data.ipwm_data.time_stamp2[i] = 0;
        ICUD_0.data.ipwm_data.pulse_width_numbers[i] = 0;
        ICUD_0.data.ipm_data.time_stamp1[i] = 0;
        ICUD_0.data.ipm_data.time_stamp2[i] = 0;
        ICUD_0.data.ipm_data.period_numbers[i] = 0;
    }

    for (i = 0U; i < 14U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, ch_num[i], &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, ch_num[i]);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, ch_num[i]);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, ch_num[i]);
        PSPRINTF("\n chnnel_number = %d!\n", ch_num[i]);
        PSPRINTF("\n time_stamp2 =  %d !\n", ICUD_0.data.ipwm_data.time_stamp2[ch_num[i]]);
        PSPRINTF("\n time_stamp1 =  %d !\n", ICUD_0.data.ipwm_data.time_stamp1[ch_num[i]]);
    }
}

/*******************************************************************************
 * @brief      ICU_Test_Case8
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ICU_Test_Case8(void) /* PRQA S 3219 */
{
    uint8_t i = 0;
    uint8_t const ch_num[14] = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15};
    ICUConfig_t config;

    cc_memset((uint8_t *)&config, 0, sizeof(config));

    /* Set config parameters */
    config.hw_mode = ICU_INPUT_PERIOD_WIDTH_MEASUREMENT_MODE;
    config.config_ipm.clock_bus = ICU_COUNTER_BUS_A;
    config.config_ipm.uc_prescale = ICU_UC_PRESCALE_DIV1;
    config.config_ipm.edge_polarity = RISING_EDGE;
    config.config_ipm.ipw_cb = icuipmcb1;

    PWM_MCB_ICU_USE();

    /* icudriver Init*/
    ICUD_0.emiosp = &EMIOS_0;
    ICUD_0.ch_num.R = 0;
    ICUD_0.sys_clock = 64000000;
    ICUD_0.emios_prescale = 64;

    for (i = 0U; i < 32U; i++)
    {
        ICUD_0.data.saic_data.edge_numbers[i] = 0;
        ICUD_0.data.saic_data.time_stamp[i] = 0;
        ICUD_0.data.saic_data.width[i] = 0;
        ICUD_0.data.saic_data.pe.a2_1 = 0;
        ICUD_0.data.saic_data.pe.a2_2 = 0;
        ICUD_0.data.saic_data.pe.a2_3 = 0;
        ICUD_0.data.saic_data.period[i] = 0;
        ICUD_0.data.ipwm_data.time_stamp1[i] = 0;
        ICUD_0.data.ipwm_data.time_stamp2[i] = 0;
        ICUD_0.data.ipwm_data.pulse_width_numbers[i] = 0;
        ICUD_0.data.ipm_data.time_stamp1[i] = 0;
        ICUD_0.data.ipm_data.time_stamp2[i] = 0;
        ICUD_0.data.ipm_data.period_numbers[i] = 0;
    }

    for (i = 0U; i < 14U; i++)
    {
        ICU_LLD_UC_Channel_Init(&ICUD_0, ch_num[i], &config);
        ICU_LLD_Interrupt_Register(&ICUD_0, ch_num[i]);
        ICU_LLD_UC_Channel_Enable(&ICUD_0, ch_num[i]);
        delay_ms(500);
        ICU_LLD_UC_Channel_Disable(&ICUD_0, ch_num[i]);
        PSPRINTF("\n chnnel_number = %d!\n", ch_num[i]);
        PSPRINTF("\n time_stamp2 time = %d !\n", ICUD_0.data.ipm_data.time_stamp2[ch_num[i]]);
        PSPRINTF("\n time_stamp1 time = %d !\n", ICUD_0.data.ipm_data.time_stamp1[ch_num[i]]);
    }
}

/*******************************************************************************
 * @brief      ICU_TEST_Demo
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
void ICU_TEST_Demo(void)
{
    int32_t test_cnt = 100;

    PSPRINTF("\n ICU Test Start!\n");
    /* Set the current priority */
    INTC_CPR_Init((uint8_t)CPR_PRI_0);

    while ((test_cnt--) != 0) /* PRQA S 3440 */
    {
    /* Function:  input capture rising edge_numbers using internal clock*/	
#if ICU_CASE1
        ICU_Test_Case1();
#endif

	/* Function:  input capture rising time_stamp using internal clock*/	
#if ICU_CASE2
        ICU_Test_Case2();
#endif

	/* Function:  input capture measure PWM Frequency and DutyCycle*/        
#if ICU_CASE3
        ICU_Test_Case3();
#endif

	/* Function:  input pulse width measure using internal clock*/
#if ICU_CASE4
        ICU_Test_Case4();
#endif

	/* Function:  input pulse period width measure using internal clock*/
#if ICU_CASE5
        ICU_Test_Case5();
#endif

	/* Function:  input capture rising edge_numbers using BUS_A clock*/
#if ICU_CASE6
        ICU_Test_Case6();
#endif

	/* Function:  input pulse width measure using BUS_A clock*/
#if ICU_CASE7
        ICU_Test_Case7();
#endif

	/* Function:  input pulse period width measure using BUS_A clock*/
#if ICU_CASE8
        ICU_Test_Case8();
#endif
    }

    PSPRINTF("\n ICU Test End!\n");
}

